package com.basicalg.basicalgorithms;

import com.basicalg.constants.AlgorithmTypes;
import com.basicalg.helper.AlgHelper;
import com.basicalg.impls.SelectionSort;
import com.dlsc.formsfx.model.validators.RegexValidator;
import javafx.application.Application;
import javafx.collections.ObservableList;
import javafx.geometry.Insets;
import javafx.geometry.Pos;
import javafx.scene.Node;
import javafx.scene.Scene;
import javafx.scene.control.*;
import javafx.scene.layout.HBox;
import javafx.scene.layout.VBox;
import javafx.stage.PopupWindow;
import javafx.stage.Stage;
import javafx.stage.Window;
import javafx.util.Callback;
import javafx.util.Pair;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Objects;

public class MainApp extends Application {
    ComboBox<Pair<AlgorithmTypes,String>> algTypeCombo = new ComboBox<>();
    TextField arrayInput = new TextField();
    Button analysisBtn = new Button("计算轨迹");
    AlgorithmTypes currAlgorithm;
    private final static Pair<AlgorithmTypes, String> EMPTY_PAIR = new Pair<>(AlgorithmTypes.None,"");
    @Override
    public void start(Stage primaryStage) throws Exception {

        VBox vBoxTrack = new VBox();
        vBoxTrack.setAlignment(Pos.CENTER_LEFT);
        vBoxTrack.setSpacing(4);
        vBoxTrack.setPadding(new Insets(10.0d));
        arrayInput.setPrefWidth(300);
        arrayInput.setAlignment(Pos.BASELINE_LEFT);
        analysisBtn.setAlignment(Pos.BASELINE_RIGHT);
        arrayInput.setPromptText("Please input the arrays you want to test!");
        initCombo();
        algTypeCombo.setPrefWidth(200);
        algTypeCombo.setOnAction((evt)-> {
             currAlgorithm = algTypeCombo.getValue().getKey();
            System.out.println(currAlgorithm);
        });

        analysisBtn.setOnMouseClicked((evt) -> {
            String inputText = arrayInput.getText();
            System.out.println(inputText);
            String[] inputArr = inputText.split(",");
            if (inputText.length() > 1 && inputArr.length > 1) {
                int[] arr = AlgHelper.ParserToInt(inputArr);
                ObservableList<Node> oldPanes = vBoxTrack.getChildren();
                vBoxTrack.getChildren().removeAll(oldPanes);
                if (currAlgorithm == AlgorithmTypes.SelectionSort) {
                    List<HBox> panes =SelectionSort.getSortPanes(arr);
                    vBoxTrack.getChildren().addAll(panes);
                }
            } else {
                Dialog<String> dialog = new Dialog<>();
                ButtonType closeBtnType = new ButtonType("Close", ButtonBar.ButtonData.CANCEL_CLOSE);
                dialog.setTitle("Message");
                dialog.setContentText("The input format is not correct! Or not select the algorithm");
                dialog.getDialogPane().getButtonTypes().add(closeBtnType);
                dialog.showAndWait();
            }
        });
        VBox vBoxContainer = new VBox(
                algTypeCombo,
                arrayInput,
                analysisBtn,
                vBoxTrack
        );

        Scene scene = new Scene(vBoxContainer);
        primaryStage.setScene(scene);
        primaryStage.setWidth(800);
        primaryStage.setMinHeight(800);
        primaryStage.setTitle("App for draw algorithms states");
        primaryStage.show();
    }

    public static void main(String[] args) {
        launch(args);
    }

    private void initCombo() {
        List<Pair<AlgorithmTypes,String>> algTypes = new ArrayList<>();
        algTypes.add(new Pair<>(AlgorithmTypes.SelectionSort, "Selection Sort"));
        algTypes.add(new Pair<>(AlgorithmTypes.InsertionSort, "Insertion Sort"));
        algTypes.add(new Pair<>(AlgorithmTypes.MergeSort,"Merge Sort"));
        algTypes.add(new Pair<>(AlgorithmTypes.ShellSort,"Shell Sort"));
        algTypes.add(new Pair<>(AlgorithmTypes.QuickSort,"Quick Sort"));
        algTypes.add(new Pair<>(AlgorithmTypes.HeapSort,"Heap Sort"));

        algTypeCombo.getItems().add(EMPTY_PAIR);
        algTypeCombo.getItems().addAll(algTypes);

        Callback<ListView<Pair<AlgorithmTypes,String>>, ListCell<Pair<AlgorithmTypes,String>>> factory = (lv) ->
                new ListCell<>() {
                    @Override
                    protected void updateItem(Pair<AlgorithmTypes, String> item, boolean empty) {
                        super.updateItem(item, empty);
                        if (empty) {
                            setText("");
                        } else {
                            setText(item.getValue());
                        }
                    }
                };
        algTypeCombo.setCellFactory(factory);
        algTypeCombo.setButtonCell(factory.call(null));
    }
}
